package com.st.rzs.solr.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.SortClause;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;

import com.st.rzs.solr.connection.SolrConncetionFactory;

/**
 * 
 * desc:solr基本操作
 * 
 * @author wangsh
 * @date 2019-01-09 下午8:15:36
 */
public class SolrUtil {

	private static final Log log = LogFactory.getLog(SolrUtil.class);

	/**
	 * 判断表是否存在
	 * 
	 * @param tableName
	 *            ：表名称
	 * @return true存在，false不存在
	 * @throws Exception
	 * @throws IOException
	 */
	public boolean tableExists(String connectionName) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName)) {
				log.error(" param is null or empty");
				return false;
			}
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			solrServer.ping();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("solr core not exists : " + e.getMessage());
		}
		return true;
	}

	/**
	 * 删除指定的表
	 * 
	 * @param tableName
	 *            ：表名称
	 * @throws Exception
	 */
	public void deleteTable(String connectionName) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName)) {
				log.error(" param is null or empty");
				return;
			}
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			solrServer.deleteByQuery("*:*");
			solrServer.commit();
		} catch (SolrServerException | IOException e) {
			e.printStackTrace();
			log.error("delete connection data failure ： " + e.getMessage());
		}
	}

	/**
	 * 
	 * @Description:根据id删除
	 * @param connectionName
	 * @param condition
	 * @throws Exception
	 * @return void 返回类型
	 * @throws
	 */
	public void deleteById(String connectionName, String id) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName) || StringUtils.isEmpty(id)) {
				log.error(" param is null or empty");
				return;
			}
			// 创建solr对象
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			// 根据id删除索引"A1000"
			solrServer.deleteById(id);
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("delete connection data failure ： " + e.getMessage());
		}

	}

	/**
	 * 
	 * @Description:根据id删除
	 * @param connectionName
	 * @param condition
	 * @throws Exception
	 * @return void 返回类型
	 * @throws
	 */
	public void deleteById(String connectionName, List<String> ids) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName) || ids == null || ids.size() < 0) {
				log.error(" delete param is null or empty");
				return;
			}
			// 创建solr对象
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			// 根据id删除索引"A1000"
			solrServer.deleteById(ids);
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("delete connection data failure ： " + e.getMessage());
		}

	}

	/**
	 * 
	 * @Description:根据条件删除
	 * @param connectionName
	 * @param condition
	 *            ：删除sql条件；例如：id:A1000 and (age[1 TO 100 ])
	 * @throws Exception
	 * @return void 返回类型
	 * @throws
	 */
	public void deleteByQuery(String connectionName, String condition) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName) || StringUtils.isEmpty(condition)) {
				log.error(" delete param is null or empty");
				return;
			}
			// 创建solr对象
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			// 根据id删除索引"id:A1000"
			solrServer.deleteByQuery(condition);
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("delete connection data failure ： " + e.getMessage());
		}

	}

	/**
	 * @throws Exception
	 * 
	 * @Description:使用solr操作
	 * @param connectionName
	 *            ：solrcore名称
	 * @param docs
	 * @return void 返回类型
	 * @throws
	 */
	public void batchUpdate(String connectionName, List<SolrInputDocument> docs) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName) || docs == null || docs.size() <= 0) {
				log.error("  add data to solr param is null or empty");
				return;
			}
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			solrServer.add(docs);
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("add connection data failure ： " + e.getMessage());
		}
	}

	/**
	 * @throws Exception
	 * 
	 * @Description:使用solrcloud云操作
	 * @param connectionName
	 *            ：solrcore名称
	 * @param docs
	 * @return void 返回类型
	 * @throws
	 */
	public void batchCloudUpdate(String connectionName, List<SolrInputDocument> docs) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName) || docs == null || docs.size() <= 0) {
				log.error("  batchCloudUpdate data to solr param is null or empty");
				return;
			}
			CloudSolrServer solrServer = SolrConncetionFactory.getColudConnection(connectionName);
			solrServer.connect();
			solrServer.add(docs);
			solrServer.commit(false, false);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("add connection data failure ： " + e.getMessage());
		}
	}

	/**
	 * 
	 * @Description:创建索引
	 * @param connectionName
	 *            ： ：solrcore名称
	 * @param fields
	 *            ：保存索引及值
	 * @throws Exception
	 * @return void 返回类型
	 * @throws
	 */
	public void put(String connectionName, List<Map<String, Object>> fields) throws Exception {

		try {
			if (StringUtils.isEmpty(connectionName) || fields == null || fields.size() <= 0) {
				log.error(" add data to solr param is null or empty");
				return;
			}
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			SolrInputDocument document = new SolrInputDocument();
			for (Map<String, Object> fieldMap : fields) {
				for (String key : fieldMap.keySet()) {
					document.addField(key, fieldMap.get(key));
				}
			}
			solrServer.add(document);
			// 提交
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("add connection data failure ： " + e.getMessage());
		}
	}

	/**
	 * 
	 * @Description:查询
	 * @date:Dec 21, 2017 7:21:06 PM
	 * @param connectionName
	 *            ：连接solrcore名称
	 * @param queryCondition
	 *            :查询条件语句.例如：id:A1000 and (age[1 TO 100 ])
	 * @return
	 * @throws Exception
	 * @return SolrDocumentList 返回类型
	 * @throws
	 */
	public SolrDocumentList get(String connectionName, String queryCondition) throws Exception {

		SolrDocumentList docs = null;
		try {
			if (StringUtils.isEmpty(connectionName)) {
				log.error(" param is null or empty");
				return null;
			}
			SolrQuery query = null;
			if (StringUtils.isEmpty(queryCondition)) {
				query = new SolrQuery();
			} else {
				query = new SolrQuery(queryCondition);
			}
			// 查询
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			QueryResponse response = solrServer.query(query);
			docs = response.getResults();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("get connection data failure ： " + e.getMessage());
		}
		return docs;
	}

	/**
	 * 
	 * @Description:查询
	 * @date:Dec 21, 2017 7:21:06 PM
	 * @param connectionName
	 *            ：连接solrcore名称
	 * @param queryCondition
	 *            :查询条件语句.例如：id:A1000 and (age[1 TO 100 ])
	 * @param startRow
	 *            :数据起始行，分页用
	 * @param pageSize
	 *            ：返回记录数，分页用
	 * @param sortList
	 *            ：排序字段
	 * @param fieldList
	 *            ：指定查询字段
	 * @param highlightField
	 *            :高亮字段，以空格或者英文逗号隔开;例如：username password sex
	 *            age或者username,password,sex,age
	 * @return
	 * @throws Exception
	 * @return SolrDocumentList 返回类型
	 * @throws
	 */
	public ResultInfo query(String connectionName, String queryCondition, List<String> fieldList, String highlightField) throws Exception {

		ResultInfo resultInfo = this.queryByPage(connectionName, queryCondition, null, null, null, null);
		return resultInfo;
	}

	/**
	 * 
	 * @Description:查询
	 * @date:Dec 21, 2017 7:21:06 PM
	 * @param connectionName
	 *            ：连接solrcore名称
	 * @param queryCondition
	 *            :查询条件语句.例如：id:A1000 and (age[1 TO 100 ])
	 * @param startRow
	 *            :数据起始行，分页用
	 * @param pageSize
	 *            ：返回记录数，分页用
	 * @param sortList
	 *            ：排序字段
	 * @param fieldList
	 *            ：指定查询字段
	 * @param highlightField
	 *            :高亮字段，以空格或者英文逗号隔开;例如：username password sex
	 *            age或者username,password,sex,age
	 * @return
	 * @throws Exception
	 * @return SolrDocumentList 返回类型
	 * @throws
	 */
	@SuppressWarnings("rawtypes")
	public static ResultInfo queryByPage(String connectionName, String queryCondition, Integer startRow, Integer pageSize, List<String> fieldList,
			String highlightField) throws Exception {

		ResultInfo resultInfo = new ResultInfo();
		try {
			if (StringUtils.isEmpty(connectionName)) {
				log.error(" param is null or empty");
				return null;
			}
			SolrQuery query = null;
			if (StringUtils.isEmpty(queryCondition)) {
				query = new SolrQuery();
			} else {
				query = new SolrQuery(queryCondition);
			}
			if (startRow != null && startRow >= 0) {
				query.setStart(startRow); // 数据起始行，分页用
			}
			if (pageSize != null && pageSize > 0) {
				query.setRows(pageSize); // 返回记录数，分页用
			}

			// query.setSorts(sortList);

			// 指定查询那些内容
			if (fieldList != null && fieldList.size() > 0) {
				query.setFields((String[]) fieldList.toArray());
			}
			// 高亮
			if (StringUtils.isNotBlank(highlightField)) {
				query.setHighlight(true);
				query.addHighlightField(highlightField);
				query.setHighlightSimplePre("<font color='red'>");
				query.setHighlightSimplePost("</font>");
			}
			// 查询
			HttpSolrServer solrServer = SolrConncetionFactory.getConnection(connectionName);
			QueryResponse response = solrServer.query(query);
			SolrDocumentList docs = response.getResults();// 结果
			Long total = response.getResults().getNumFound();// 总数
			// 高亮数据
			Map<String, Map<String, List<String>>> hlMap = response.getHighlighting();

			List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();
			for (SolrDocument doc : docs) {
				Map<String, Object> map = new HashMap<String, Object>();
				for (String fileName : doc.getFieldNames()) {
					boolean bool = (hlMap != null && hlMap.size() > 0 && hlMap.containsKey(doc.get("id")))
							&& hlMap.get(doc.get("id")).containsKey(fileName);
					Object value = bool ? hlMap.get(doc.get("id")).get(fileName).get(0) : doc.getFieldValue(fileName);
					map.put(fileName, value);
				}
				resList.add(map);
			}
			resultInfo.setList(resList);
			resultInfo.setTotal(total);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("get connection data failure ： " + e.getMessage());
		}
		return resultInfo;
	}

}
